package com.schoolcloud.auth.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import com.schoolcloud.common.model.UserInfo;
import com.schoolcloud.auth.dto.FroUserEnrollDTO;
import com.schoolcloud.common.model.FrontUserLoginDTO;
import com.schoolcloud.common.model.R;
import com.schoolcloud.api.client.front.FrontUserClient;
import com.schoolcloud.api.client.SystemClient;
import com.schoolcloud.api.dto.LoginModel;
import com.schoolcloud.auth.util.FroUserStpUtil;
import com.wf.captcha.SpecCaptcha;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("auth")
@RequiredArgsConstructor
@Slf4j
public class AuthController {
    private final String KEY_PREFIX = "login-key:";
    private final RedisTemplate<String, String> redisTemplate;

    private final SystemClient sysUserFeignService;
    private final FrontUserClient frontFeignService;

    @PostMapping("/admin/login")
    public R sysUserLogin(@RequestBody LoginModel loginModel) {
        //验证验证码的正确性
        String path = KEY_PREFIX + loginModel.getCaptchaKey();
        String s = redisTemplate.opsForValue().get(path);
        if (s == null || !s.equals(loginModel.getCaptchaValue())) {
            return R.err("验证码错误!");
        }
        //        远程调用system服务获取用户Id
        R<String> r = sysUserFeignService.login(loginModel);
//        设置登录凭证
        StpUtil.login(r.getData());
//        返回token
        return R.ok("登录成功",StpUtil.getTokenValue());
    }

    @RequestMapping("/admin/logout")
    public R sysUserLogout() {
        StpUtil.logout();
        return R.ok();
    }

    @PostMapping("/front/login")
    public R FroUserLogin(@RequestBody FrontUserLoginDTO loginModel) {
//        检测验证码
        String captchaKey = loginModel.getCaptchaId();
        String path = KEY_PREFIX + captchaKey;
        String s = redisTemplate.opsForValue().get(path);
        if (s == null || !s.equals(loginModel.getCaptcha())) {
//            删掉验证码
            redisTemplate.delete(path);
            return R.err("验证码错误!");
        }
//        远程调用system服务获取用户Id
        R<UserInfo> r = frontFeignService.login(loginModel);
        UserInfo user = r.getData();
        if (ObjUtil.isEmpty(user)) {
            log.info("这一步应该不会被执行！");
            return R.err("用户名或密码错误");
        }
//        设置登录凭证
        FroUserStpUtil.login(user.getUserId());
//        返回token
        return R.ok("登录成功",FroUserStpUtil.getTokenValue());
    }

    @PostMapping("/front/enroll")
    public R FroUserEnroll(@RequestBody FroUserEnrollDTO dto) {
        String phone = dto.getPhone();
        String captcha = dto.getCaptcha();
        String path = KEY_PREFIX + phone;
        String s = redisTemplate.opsForValue().get(path);
        if (s == null || !s.equals(captcha)) {
            return R.err("验证码错误!");
        }
        redisTemplate.delete(path);
        UserInfo froUser = new UserInfo();
        BeanUtils.copyProperties(dto, froUser);
        return frontFeignService.saveUser(froUser);
    }

    @RequestMapping("/front/logout")
    public R FroUserLogout() {
        FroUserStpUtil.logout();
        return R.ok("注销成功！");
    }

    /**
     * 获取验证码
     *
     * @return {@link R}<{@link Map}<{@link String}, {@link String}>>
     */
    @RequestMapping("/captcha")
    public R<Map<String, String>> loginCaptcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        String verCode = specCaptcha.text().toLowerCase();
        String key = UUID.randomUUID().toString();
        String path = KEY_PREFIX + key;
        // 存入redis并设置过期时间为2分钟
        redisTemplate.opsForValue().set(path, verCode, 10, TimeUnit.MINUTES);
        HashMap<String, String> map = new HashMap<>();
        map.put("captchaKey", key);
        map.put("captchaImage", specCaptcha.toBase64());
        log.info("验证码key为：code:{},验证码值为：value:{}", key, verCode);
        // 将key和base64返回给前端
        return R.ok(map);
    }

    @RequestMapping("/phone/captcha")
    public R<Map<String, String>> phoneCaptcha(@RequestParam String phone) {
//     todo   暂时模拟手机验证码，后续考虑集成短信服务在实现
        String verCode = RandomUtil.randomNumbers(6);
        String path = KEY_PREFIX + phone;
        redisTemplate.opsForValue().set(path, verCode, 10, TimeUnit.MINUTES);
        HashMap<String, String> map = new HashMap<>();
        map.put("captchaKey", phone);
        map.put("captcha", verCode);//todo 开发阶段为了简便，直接返回验证码，后续需要删除
        return R.ok(map);
    }
}
